package com.rs2hd.packethandler;

import com.rs2hd.Constants;
import com.rs2hd.model.*;
import com.rs2hd.net.Packet;
import com.rs2hd.script.ScriptManager;
import com.rs2hd.util.log.Logger;
import org.apache.mina.common.IoSession;
import com.rs2hd.event.Event;

/**
 * Handles all packets to do with items.
 *
 * @author Graham
 */
public class ItemPacketHandler implements PacketHandler {
	private final Logger logger = Logger.getInstance();

	@Override
	public void handlePacket(final Player player, final IoSession session, final Packet packet) {
		switch (packet.getId()) {
		case 253:
			/*
			 * Switch items.
			 */
			switchItems(player, session, packet);
			break;
		case 179:
			/*
			 * Transfer items between two interfaces.
			 */
			switchItems2(player, session, packet);
			break;
		case 229: //is that right packet when i clicked claws it came up and i asked sum1 and they said yesk
			/*
			 * Equip.
			 */
			equip(player, session, packet);
			break;
		case 234:
			/*
			 * Item option 1.
			 */
			itemOption1(player, session, packet);
			break;
		case 152:
			/*
			 * Item option 2.
			 */
			itemOption2(player, session, packet);
			break;
		case 66:
			/*
			 * Item select.
			 */
			itemSelect(player, session, packet);
			break;
		case 186:
			/*
			 * Item operate.
			 */
			itemOperate(player, session, packet);
			break;
		case 248:
			/*
			 * Drop item.
			 */
			drop(player, session, packet);
			break;
		case 194:
			/*
			 * Take item.
			 */
			take(player, session, packet);
			break;
		case 117:
			/*
			 * Item on item.
			 */
			itemOnItem(player, session, packet);
			break;
		case 202:
			/*
			 * Item on object.
			 */
			itemOnObject(player, session, packet);
			break;
		case 131:
			/*
			 * Item on player.
			 */
			itemOnPlayer(player, session, packet);
			break;
		case 12:
			/*
			 * Item on npc.
			 */
			itemOnNPC(player, session, packet);
			break;
		}
	}

	private void itemOnPlayer(final Player player, final IoSession session, final Packet packet) {
		packet.readInt();// junk
		final int playerId = packet.readShort() & 0xFFFF;
		final int slot = packet.readLEShortA() & 0xFFFF;
		final int id = packet.readShortA() & 0xFFFF;
		if (playerId < 0 || playerId >= Constants.PLAYER_CAP) {
			return;
		}
		final Player other = World.getInstance().getPlayerList().get(playerId);
		if (other == null) {
			return;
		}
		if (slot < 0 || slot >= Inventory.SIZE) {
			return;
		}
		final Item item = player.getInventory().getContainer().get(slot);
		if (item == null || item.getId() != id) {
			return;
		}
		ScriptManager.getInstance().invoke("item_on_player_" + id, player, slot, other);
	}

	private void itemOnNPC(final Player player, final IoSession session, final Packet packet) {
		packet.readInt(); // junk
		final int npcId = packet.readShort() & 0xFFFF;
		final int slot = packet.readLEShortA() & 0xFFFF;
		final int id = packet.readShortA() & 0xFFFF;
		if (npcId < 0 || npcId >= Constants.NPC_CAP) {
			return;
		}
		final NPC npc = World.getInstance().getNpcList().get(npcId);
		if (npc == null) {
			return;
		}
		if (slot < 0 || slot >= Inventory.SIZE) {
			return;
		}
		final Item item = player.getInventory().getContainer().get(slot);
		if (item == null || item.getId() != id) {
			return;
		}
		ScriptManager.getInstance().invoke("item_on_npc_" + id, player, slot, npc);
	}

	private void itemOnObject(final Player player, final IoSession session, final Packet packet) {
		@SuppressWarnings("unused")final int objectY = packet.readLEShort() & 0xFFFF;
		final int objectId = packet.readLEShort() & 0xFFFF;
		@SuppressWarnings("unused") final int unknown = packet.readShortA() & 0xFFFF;//Value : 128 ? 200;
		final int interfaceId = packet.readShort() & 0xFFFF;
		final int itemId = packet.readShortA() & 0xFFFF;
		@SuppressWarnings("unused") final int itemSlot = packet.readShortA() & 0xFFFF;
		@SuppressWarnings("unused")final int objectX = packet.readLEShort() & 0xFFFF;
		@SuppressWarnings("unused") final int slot = player.getInventory().lookupSlot(itemId);
		if (interfaceId != 149) {//Player is not in invy screen
			return;
		}
		player.getCooking().handleItemOnObject(itemId, objectId);
		player.getSmithing().itemOnObject(player,itemId, objectId);
	}

	private void itemOnItem(final Player player, final IoSession session, final Packet packet) {
		final int interfaceIndex = packet.readShort();
		@SuppressWarnings("unused") final int junk1 = packet.readLEShortA() & 0xFFFF;
		@SuppressWarnings("unused") final int junk2 = packet.readLEShort() & 0xFFFF;
		@SuppressWarnings("unused") final int junk3 = packet.readLEShortA() & 0xFFFF;
		final int itemUsed = packet.readLEShortA() & 0xFFFF;
		@SuppressWarnings("unused") final int junk4 = packet.readLEShortA() & 0xFFFF;
		@SuppressWarnings("unused") final int junk5 = packet.readLEShortA() & 0xFFFF;
		final int usedWith = packet.readLEShort() & 0xFFFF;
		if (interfaceIndex != 149) {
			return;
		}
		System.out.println("ITEM 1: " +itemUsed+ " ITEM 2: " +usedWith);
	}

	private void itemOperate(final Player player, final IoSession session, final Packet packet) {
		final int interfaceSet = packet.readInt();
		final int interfaceId = interfaceSet >> 16;
		final int id = packet.readShortA() & 0xFFFF;
		final int slot = packet.readLEShortA() & 0xFFFF;
		if (interfaceId == 7168) {
			if (slot < 0 || slot >= Equipment.SIZE || player.getEquipment().getContainer().get(slot) == null) {
				return;
			}
			if (player.getEquipment().getContainer().get(slot).getId() != id) {
				return;
			}
			ScriptManager.getInstance().invoke("item_operate_" + id, player, slot);
		} else {
			logger.debug("Unhandled item operate, interface: " + interfaceId + ".");
		}
	}

	private void itemSelect(final Player player, final IoSession session, final Packet packet) {
		final int interfaceId = packet.readShort();
		@SuppressWarnings("unused") final int junk = packet.readShort();
		final int id = packet.readShort();
		final int slot = packet.readShortA();
			int itemId = id;
		if (interfaceId == 149) {
		switch (id) {

		case 8013:
		        player.tele(2852 ,2954 , 0);
                        player.getActionSender().sendMessage("You Break The Teletab.");
		 	player.getInventory().deleteItem(8013, 1);

		break;

			case 139:
			case 141:
			case 143:
			if (player.potDelay == 0) {
			player.getInventory().deleteItem(itemId, 1);
				if (itemId != 143) {
					player.getInventory().addItem(itemId+2, 1);
				} else {
					player.getInventory().addItem(229, 1);
				}
					int abc = (int) ((player.getSkills().getLevelForXp(5)/4) + 7);
					player.getSkills().RestorePray(abc);
					player.animate(829, 0);
					player.getCombat().combatDelay += 4;
					player.potDelay = 3;
			}
			break;
                        case 391:
			if (player.potDelay == 0) {
			player.potDelay = 3;
		 	player.getInventory().deleteItem(id, 1);
			player.getCombat().combatDelay += 3;
			player.getSkills().heal(22);
			player.animate(829);
                        player.getActionSender().sendMessage("You Eat The Mantas Ray.");
}
                        break;
                        case 536:
                         player.animate(827, 0);
		 	   player.getInventory().deleteItem(536, 1);
                            player.getSkills().addXp(5, 10000);
                              player.getActionSender().sendMessage("You Dig A Hole On The Ground...");
                                 player.getActionSender().sendMessage("You Bury The Dragon Bone.");
                        break;
			case 2434:
				if (player.potDelay == 0) {
					player.getInventory().deleteItem(itemId, 1);
					player.getInventory().addItem(139, 1);
					int abc = (int) ((player.getSkills().getLevelForXp(5)/4) + 7);
					player.getSkills().RestorePray(abc);
					player.animate(829, 0);
					player.getCombat().combatDelay += 4;
					player.potDelay = 3;
				}
			break;
			default:
				ScriptManager.getInstance().invoke("item_select_"+id, player, slot);
			break;
		}
		} else {
		}
	}


	private void itemOption2(final Player player, final IoSession session, final Packet packet) {
		final int slot = packet.readLEShortA() & 0xFFFF;
		final int id = packet.readShortA() & 0xFFFF;
		final int interfaceSet = packet.readInt();
		final int interfaceId = interfaceSet >> 16;
		if (interfaceId == 149) {
			if (slot < 0 || slot >= Inventory.SIZE || player.getInventory().getContainer().get(slot) == null) {
				return;
			}
			if (player.getInventory().getContainer().get(slot).getId() != id) {
				return;
			}
			ScriptManager.getInstance().invoke("item_option_2_" + id, player, slot);
		} else {
			logger.debug("Unhandled item option 2, interface: " + interfaceId + ".");
		}
	}

	private void take(final Player player, final IoSession session, final Packet packet) {
		final int y = packet.readLEShortA() & 0xFFFF;
		final int id = packet.readShortA() & 0xFFFF;
		final int x = packet.readLEShortA() & 0xFFFF;
		final Location l = Location.location(x, y, player.getLocation().getZ());
		player.getWalkingQueue().reset();
		int toX = x - (player.getLocation().getRegionX() - 6) * 8;
		int toY = y - (player.getLocation().getRegionY() - 6) * 8;
		player.getWalkingQueue().addToWalkingQueue(toX, toY);
		if (player.getLocation().getX() == x && player.getLocation().getY() == y) {
			if (World.getInstance().getItemManager().groundItemExists(l, id)) {
				final int itemAmount = World.getInstance().getItemManager().getItemAmount(l, id);
				assert itemAmount != -1;
				if (player.getInventory().hasRoomFor(id, itemAmount)) {
					World.getInstance().getItemManager().destroyGroundItem(l, id);
					player.getInventory().addItem(id, itemAmount);
				} else {
					player.getActionSender().sendMessage("Not enough space in your inventory.");
				}
			}
		}
	}

	private void drop(final Player player, final IoSession session, final Packet packet) {
		packet.readInt();
		final int slot = packet.readShortA() & 0xFFFF;
		@SuppressWarnings("unused")
		final
		int id = packet.readLEShort() & 0xFFFF;
		if (slot < 0 || slot >= Inventory.SIZE || player.getInventory().getContainer().get(slot) == null) {
			return;
		}
		final Item item = player.getInventory().getContainer().get(slot);
		player.getInventory().getContainer().set(slot, null);
		player.getInventory().refresh();
		World.getInstance().getItemManager().createGroundItem(player, item);
	}

	private void switchItems2(final Player player, final IoSession session, final Packet packet) {
		final int interface1 = packet.readInt() >> 16;
		packet.readInt();
		final int fromId = packet.readShort() & 0xFFFF;
		final int toId = packet.readLEShort() & 0xFFFF;
		switch (interface1) {
		case 762:
			/*
			 * Bank.
			 */
			if (fromId < 0 || fromId >= Bank.SIZE || toId < 0 || toId >= Bank.SIZE) {
				break;
			}
			Item temp = player.getBank().getContainer().get(fromId);
			Item temp2 = player.getBank().getContainer().get(toId);
			player.getBank().getContainer().set(fromId, temp2);
			player.getBank().getContainer().set(toId, temp);
			player.getBank().refresh();
			break;
		case 763:
			/*
			 * Inventory.
			 */
			if (fromId < 0 || fromId >= Inventory.SIZE || toId < 0 || toId >= Inventory.SIZE) {
				break;
			}
			temp = player.getInventory().getContainer().get(fromId);
			temp2 = player.getInventory().getContainer().get(toId);
			player.getInventory().getContainer().set(fromId, temp2);
			player.getInventory().getContainer().set(toId, temp);
			player.getBank().refresh();
			break;
		}
	}

	private void itemOption1(final Player player, final IoSession session, final Packet packet) {
		final int interfaceId = packet.readShort();
		@SuppressWarnings("unused")
		final
		int junk = packet.readLEShortA() & 0xFF;
		final int itemId = packet.readShortA();
		final int slot = packet.readLEShort();
		if (slot < 0 || itemId < 0) {
			return;
		}
		switch (interfaceId) {
		case 387:
			/*
			 * Unequip item.
			 */
			if (slot < Equipment.SIZE && player.getEquipment().get(slot) != null) {
				if (!player.getInventory().addItem(player.getEquipment().get(slot).getDefinition().getId(), player.getEquipment().get(slot).getAmount())) {
					break;
				}
				player.getEquipment().set(slot, null);
				player.getActionSender().sendTabs();
			}
			break;
		case 149:
			if (slot < 0 || slot >= Inventory.SIZE || player.getInventory().getContainer().get(slot) == null) {
				return;
			}
			if (player.getInventory().getContainer().get(slot).getId() != itemId) {
				return;
			}
			ScriptManager.getInstance().invoke("item_option_1_" + itemId, player, slot);
			break;
		default:
			logger.debug("Unhandled item option 1, interface: " + interfaceId + ".");
		break;
		}
	}

	private void equip(final Player player, final IoSession session, final Packet packet) { //does message working?
		@SuppressWarnings("unused")
		final int a = packet.readInt1();
		final int wearId = packet.readLEShortA();
		final int index = packet.readLEShortA();
		if (index < 0 || index >= Inventory.SIZE) {
			return;
		}
		final Item item = player.getInventory().getContainer().get(index);
		if (item == null) {
			return;
		}
		if (Equipment.isTwoHanded(item.getDefinition()) && player.getInventory().getFreeSlots() < 1 && player.getEquipment().get(5) != null) {
			player.getActionSender().sendMessage("Not enough free space in your inventory.");
			return;
		}
		if (item.getDefinition().getId() == wearId) {
			final int targetSlot = Equipment.getItemType(wearId);
			if (targetSlot == -1) {
				return;
			}
			player.getInventory().deleteItem(item.getDefinition().getId(), item.getAmount());
			if (player.getEquipment().get(targetSlot) != null && (wearId != player.getEquipment().get(targetSlot).getDefinition().getId() || !item.getDefinition().isStackable())) {
				player.getInventory().addItem(player.getEquipment().get(targetSlot).getDefinition().getId(), player.getEquipment().get(targetSlot).getAmount());
				player.getEquipment().set(targetSlot, null);
			}
			if (targetSlot == 3) {
				if (Equipment.isTwoHanded(ItemDefinition.forId(wearId)) && player.getEquipment().get(5) != null) {
					if (!player.getInventory().addItem(player.getEquipment().get(5).getDefinition().getId(), player.getEquipment().get(5).getAmount())) {
						player.getInventory().addItem(wearId, item.getAmount());
						return;
					}
					player.getEquipment().set(5, null);
					
				}
			}
			if (targetSlot == 5) {
				if (Equipment.isTwoHanded(player.getEquipment().get(3).getDefinition()) && player.getEquipment().get(3) != null) {
					if (!player.getInventory().addItem(player.getEquipment().get(3).getDefinition().getId(), player.getEquipment().get(3).getAmount())) {
						player.getInventory().addItem(wearId, item.getAmount());
						return;
					}
					player.getEquipment().set(3, null);
				}
			}
			int oldAmt = 0;
			if (player.getEquipment().get(targetSlot) != null) {
				oldAmt = player.getEquipment().get(targetSlot).getAmount();
			}
			final Item item2 = new Item(wearId, oldAmt + item.getAmount());
			player.getEquipment().set(targetSlot, item2);
		}
		player.getActionSender().sendTabs();
	}

	private void switchItems(final Player player, final IoSession session, final Packet packet) {
		final int toId = packet.readShortA();
		packet.readByte();
		final int fromId = packet.readShort();
		packet.readShort();
		final int interfaceId = packet.readByte() & 0xFF;
		packet.readByte();
		System.out.println("ToId: "+toId+" FromId: "+fromId+" INTERFACE: "+interfaceId);
		switch (interfaceId) {
		case 149:
			/*
			 * Switch items in inventory.
			 */
			if (fromId < 0 || fromId >= Inventory.SIZE || toId < 0 || toId >= Inventory.SIZE) {
				break;
			}
			final Item temp = player.getInventory().getContainer().get(fromId);
			final Item temp2 = player.getInventory().getContainer().get(toId);
			player.getInventory().getContainer().set(fromId, temp2);
			player.getInventory().getContainer().set(toId, temp);
			break;
		default:
			logger.debug("Unhandled switch items, interface: " + interfaceId + ".");
		break;
		}
	}

}
